# -*- coding: utf-8 -*-
"""
账户管理视图控制器

处理用户账户余额、充值、交易记录等页面请求
支持学员查看余额和交易历史，管理员进行账户管理
"""

from datetime import datetime, timedelta
from decimal import Decimal
from flask import Blueprint, render_template, request, jsonify, flash, redirect, url_for, current_app
from flask_login import login_required, current_user

from app.controllers.account_controller import AccountController
from app.forms.account_forms import (
    RechargeForm, TransactionQueryForm, BalanceOperationForm,
    RefundApplicationForm, AccountSettingsForm, QuickRechargeForm
)
from app.utils.decorators import student_required, coach_required, admin_required, login_required_with_role
from app.utils.exceptions import BusinessError, ValidationError
from app.models.user import User

# 创建账户管理蓝图
accounts_bp = Blueprint('accounts', __name__)


@accounts_bp.route('/balance')
@login_required
@login_required_with_role(['student', 'coach'])
def balance():
    """
    账户余额页面

    显示用户当前余额、近期交易概览
    """
    try:
        # 获取账户概览信息
        account_summary = AccountController.get_account_summary(current_user.id)

        # 获取最近5笔交易记录
        recent_transactions = AccountController.get_transaction_history(
            current_user.id, page=1, per_page=5
        )

        # 获取本月消费统计
        monthly_stats = AccountController.get_consumption_statistics(
            current_user.id, period='month'
        )

        return render_template(
            'accounts/balance.html',
            account_summary=account_summary,
            recent_transactions=recent_transactions['transactions'],
            monthly_stats=monthly_stats,
            page_title='账户余额'
        )

    except BusinessError as e:
        flash(str(e), 'error')
        # 根据用户角色重定向到对应的仪表盘
        if current_user.role == 'coach':
            return redirect(url_for('dashboard.coach'))
        else:
            return redirect(url_for('dashboard.student'))
    except Exception as e:
        current_app.logger.error(f"加载账户余额页面失败 - 用户ID: {current_user.id}, 错误: {str(e)}")
        flash('加载页面失败，请稍后重试', 'error')
        # 根据用户角色重定向到对应的仪表盘
        if current_user.role == 'coach':
            return redirect(url_for('dashboard.coach'))
        else:
            return redirect(url_for('dashboard.student'))


@accounts_bp.route('/recharge', methods=['GET', 'POST'])
@login_required
@student_required
def recharge():
    """
    账户充值页面

    支持多种支付方式的账户充值功能
    """
    form = RechargeForm()
    quick_form = QuickRechargeForm()

    if request.method == 'POST':
        # 判断是使用哪个表单
        if 'quick_recharge' in request.form:
            # 快速充值
            if quick_form.validate_on_submit():
                try:
                    amount = quick_form.get_final_amount()
                    if not amount:
                        flash('请选择充值金额', 'error')
                        return render_template('accounts/recharge.html', form=form, quick_form=quick_form)

                    # 执行充值
                    result = AccountController.recharge_account(
                        user_id=current_user.id,
                        amount=amount,
                        payment_method=quick_form.payment_method.data
                    )

                    if result['success']:
                        flash(f'充值成功！充值金额：{amount}元，当前余额：{result["new_balance"]}元', 'success')
                        return redirect(url_for('accounts.balance'))
                    else:
                        flash('充值失败，请稍后重试', 'error')

                except BusinessError as e:
                    flash(str(e), 'error')
                except Exception as e:
                    current_app.logger.error(f"快速充值失败 - 用户ID: {current_user.id}, 错误: {str(e)}")
                    flash('充值失败，请稍后重试', 'error')

        else:
            # 普通充值
            if form.validate_on_submit():
                try:
                    # 执行充值
                    result = AccountController.recharge_account(
                        user_id=current_user.id,
                        amount=form.amount.data,
                        payment_method=form.payment_method.data
                    )

                    if result['success']:
                        flash(f'充值成功！充值金额：{form.amount.data}元，当前余额：{result["new_balance"]}元', 'success')
                        return redirect(url_for('accounts.balance'))
                    else:
                        flash('充值失败，请稍后重试', 'error')

                except BusinessError as e:
                    flash(str(e), 'error')
                except Exception as e:
                    current_app.logger.error(f"账户充值失败 - 用户ID: {current_user.id}, 错误: {str(e)}")
                    flash('充值失败，请稍后重试', 'error')

    # 获取当前账户信息用于显示
    try:
        account_summary = AccountController.get_account_summary(current_user.id)
    except BusinessError:
        account_summary = {'balance': 0, 'available_balance': 0}

    return render_template(
        'accounts/recharge.html',
        form=form,
        quick_form=quick_form,
        account_summary=account_summary,
        page_title='账户充值'
    )


@accounts_bp.route('/transactions')
@login_required
def transactions():
    """
    交易记录页面

    显示用户的交易历史，支持筛选和分页
    学员只能查看自己的交易记录，管理员可以查看指定用户的交易记录
    """
    form = TransactionQueryForm()

    # 获取查询参数
    page = request.args.get('page', 1, type=int)
    transaction_type = request.args.get('transaction_type', '')
    start_date = request.args.get('start_date', '')
    end_date = request.args.get('end_date', '')
    page_size = int(request.args.get('page_size', 20))
    user_id = request.args.get('user_id', type=int)

    # 权限验证：确定查看哪个用户的交易记录
    target_user_id = current_user.id  # 默认查看自己的记录
    target_user = current_user

    if user_id and user_id != current_user.id:
        # 如果要查看其他用户的记录，需要管理员权限
        if not (current_user.is_super_admin() or current_user.is_campus_admin()):
            flash('您没有权限查看其他用户的交易记录', 'error')
            return redirect(url_for('accounts.transactions'))

        # 验证目标用户是否存在
        target_user = User.query.get(user_id)
        if not target_user:
            flash('用户不存在', 'error')
            return redirect(url_for('accounts.transactions'))

        # 校区管理员只能查看本校区用户的记录
        if current_user.is_campus_admin() and target_user.campus_id != current_user.campus_id:
            flash('您只能查看本校区用户的交易记录', 'error')
            return redirect(url_for('accounts.transactions'))

        target_user_id = user_id

    # 验证日期格式
    start_date_obj = None
    end_date_obj = None

    if start_date:
        try:
            start_date_obj = datetime.strptime(start_date, '%Y-%m-%d')
        except ValueError:
            flash('开始日期格式错误', 'error')
            start_date = ''

    if end_date:
        try:
            end_date_obj = datetime.strptime(end_date, '%Y-%m-%d')
        except ValueError:
            flash('结束日期格式错误', 'error')
            end_date = ''

    try:
        # 获取交易记录
        transaction_data = AccountController.get_transaction_history(
            user_id=target_user_id,
            page=page,
            per_page=page_size,
            transaction_type=transaction_type if transaction_type else None,
            start_date=start_date_obj,
            end_date=end_date_obj
        )

        # 设置表单默认值
        form.transaction_type.data = transaction_type
        form.start_date.data = start_date
        form.end_date.data = end_date
        form.page_size.data = str(page_size)

        # 构建页面标题
        if target_user_id != current_user.id:
            page_title = f'{target_user.real_name}({target_user.username}) - 交易记录'
        else:
            page_title = '我的交易记录'

        return render_template(
            'accounts/transactions.html',
            form=form,
            transactions=transaction_data['transactions'],
            pagination=transaction_data,
            target_user=target_user,
            is_viewing_other_user=(target_user_id != current_user.id),
            page_title=page_title
        )

    except BusinessError as e:
        flash(str(e), 'error')
        return render_template(
            'accounts/transactions.html',
            form=form,
            transactions=[],
            pagination={'total': 0, 'pages': 0, 'current_page': 1},
            page_title='交易记录'
        )


@accounts_bp.route('/detail/<int:transaction_id>')
@login_required
def transaction_detail(transaction_id):
    """
    交易详情页面

    显示单笔交易的详细信息
    """
    try:
        # 直接通过AccountController获取特定交易详情
        transaction = AccountController.get_transaction_detail(
            transaction_id=transaction_id,
            user_id=current_user.id
        )

        if not transaction:
            flash('交易记录不存在或您没有权限查看', 'error')
            return redirect(url_for('accounts.transactions'))

        # 检查是否可以申请退款
        can_refund = (
            transaction and
            transaction.type == 'consume' and  # 只有消费记录可以退款
            transaction.amount < 0 and  # 消费记录金额为负数
            transaction.created_at > datetime.now() - timedelta(days=30)  # 30天内的记录
        )

        return render_template(
            'accounts/detail.html',
            transaction=transaction,
            can_refund=can_refund,
            page_title='交易详情'
        )

    except BusinessError as e:
        flash(str(e), 'error')
        return redirect(url_for('accounts.transactions'))
    except Exception as e:
        current_app.logger.error(f"加载交易详情失败 - 交易ID: {transaction_id}, 用户ID: {current_user.id}, 错误: {str(e)}")
        flash('加载交易详情失败，请稍后重试', 'error')
        return redirect(url_for('accounts.transactions'))


@accounts_bp.route('/statistics')
@login_required
@login_required_with_role(['student', 'coach'])
def statistics():
    """
    消费统计页面

    显示用户的消费统计图表和分析
    """
    try:
        # 获取不同时期的统计数据
        periods = ['week', 'month', 'quarter', 'year']
        statistics_data = {}

        for period in periods:
            statistics_data[period] = AccountController.get_consumption_statistics(
                current_user.id, period
            )

        # 获取账户概览
        account_summary = AccountController.get_account_summary(current_user.id)

        return render_template(
            'accounts/statistics.html',
            statistics_data=statistics_data,
            account_summary=account_summary,
            page_title='消费统计'
        )

    except BusinessError as e:
        flash(str(e), 'error')
        return redirect(url_for('accounts.balance'))
    except Exception as e:
        current_app.logger.error(f"加载消费统计失败 - 用户ID: {current_user.id}, 错误: {str(e)}")
        flash('加载统计数据失败，请稍后重试', 'error')
        return redirect(url_for('accounts.balance'))


# AJAX API 路由

@accounts_bp.route('/api/balance')
@login_required
@login_required_with_role(['student', 'coach'])
def api_get_balance():
    """
    获取账户余额 API

    返回JSON格式的账户余额信息
    """
    try:
        account_summary = AccountController.get_account_summary(current_user.id)

        return jsonify({
            'success': True,
            'data': {
                'balance': float(account_summary['balance']),
                'available_balance': float(account_summary['available_balance'])
            }
        })

    except BusinessError as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 400
    except Exception as e:
        current_app.logger.error(f"获取余额API失败 - 用户ID: {current_user.id}, 错误: {str(e)}")
        return jsonify({
            'success': False,
            'error': '获取余额失败'
        }), 500


@accounts_bp.route('/api/quick-recharge', methods=['POST'])
@login_required
@student_required
def api_quick_recharge():
    """
    快速充值 API

    处理AJAX快速充值请求
    """
    try:
        data = request.get_json()

        if not data:
            return jsonify({
                'success': False,
                'error': '无效的请求数据'
            }), 400

        amount = Decimal(str(data.get('amount', 0)))
        payment_method = data.get('payment_method', '')

        # 基本验证
        if amount <= 0:
            return jsonify({
                'success': False,
                'error': '充值金额必须大于0'
            }), 400

        if amount > Decimal('10000'):
            return jsonify({
                'success': False,
                'error': '单次充值金额不能超过10000元'
            }), 400

        # 执行充值
        result = AccountController.recharge_account(
            user_id=current_user.id,
            amount=amount,
            payment_method=payment_method
        )

        return jsonify({
            'success': True,
            'data': {
                'transaction_id': result['transaction_id'],
                'amount': float(amount),
                'new_balance': float(result['new_balance']),
                'payment_method': payment_method
            }
        })

    except BusinessError as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 400
    except ValidationError as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 400
    except Exception as e:
        current_app.logger.error(f"快速充值API失败 - 用户ID: {current_user.id}, 错误: {str(e)}")
        return jsonify({
            'success': False,
            'error': '充值失败，请稍后重试'
        }), 500


@accounts_bp.route('/api/statistics/<period>')
@login_required
@login_required_with_role(['student', 'coach'])
def api_get_statistics(period):
    """
    获取消费统计 API

    返回指定时期的消费统计数据
    """
    if period not in ['week', 'month', 'quarter', 'year']:
        return jsonify({
            'success': False,
            'error': '无效的统计周期'
        }), 400

    try:
        statistics = AccountController.get_consumption_statistics(
            current_user.id, period
        )

        # 格式化数据用于图表显示
        chart_data = {
            'labels': list(statistics.get('by_date', {}).keys()),
            'values': [float(v) for v in statistics.get('by_date', {}).values()],
            'total_income': float(statistics.get('total_income', 0)),
            'total_expense': float(statistics.get('total_expense', 0)),
            'transaction_count': statistics.get('total_transactions', 0)
        }

        return jsonify({
            'success': True,
            'data': chart_data
        })

    except BusinessError as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 400
    except Exception as e:
        current_app.logger.error(f"获取统计API失败 - 用户ID: {current_user.id}, 错误: {str(e)}")
        return jsonify({
            'success': False,
            'error': '获取统计数据失败'
        }), 500


# 管理员功能路由

@accounts_bp.route('/admin/list')
@login_required
@admin_required
def admin_account_list():
    """
    账户列表管理页面（管理员）

    显示所有用户的账户信息，支持筛选和批量操作
    """
    page = request.args.get('page', 1, type=int)
    search_query = request.args.get('search', '')
    status_filter = request.args.get('status', '')

    try:
        # 这里需要实现获取所有用户账户列表的功能
        # 暂时返回空数据，后续完善
        accounts = []
        pagination = {
            'total': 0,
            'pages': 0,
            'current_page': page,
            'has_prev': False,
            'has_next': False
        }

        return render_template(
            'accounts/admin_list.html',
            accounts=accounts,
            pagination=pagination,
            search_query=search_query,
            status_filter=status_filter,
            page_title='账户管理'
        )

    except Exception as e:
        current_app.logger.error(f"加载账户列表失败, 错误: {str(e)}")
        flash('加载账户列表失败，请稍后重试', 'error')
        return redirect(url_for('dashboard.index'))


@accounts_bp.route('/admin/user/<int:user_id>')
@login_required
@admin_required
def admin_user_account(user_id):
    """
    用户账户详情页面（管理员）

    显示指定用户的账户详细信息和操作选项
    """
    try:
        # 获取用户信息
        user = User.query.get_or_404(user_id)

        # 获取账户概览
        account_summary = AccountController.get_account_summary(user_id)

        # 获取交易记录
        transaction_data = AccountController.get_transaction_history(
            user_id=user_id,
            page=1,
            per_page=20
        )

        # 创建余额操作表单
        operation_form = BalanceOperationForm()
        operation_form.user_id.data = user_id

        return render_template(
            'accounts/admin_user_detail.html',
            user=user,
            account_summary=account_summary,
            transactions=transaction_data['transactions'],
            operation_form=operation_form,
            page_title=f'{user.username} - 账户详情'
        )

    except BusinessError as e:
        flash(str(e), 'error')
        return redirect(url_for('accounts.admin_account_list'))
    except Exception as e:
        current_app.logger.error(f"加载用户账户详情失败 - 用户ID: {user_id}, 错误: {str(e)}")
        flash('加载用户账户详情失败，请稍后重试', 'error')
        return redirect(url_for('accounts.admin_account_list'))